import puppeteer from "puppeteer";
import {EventEmitter} from 'events';
import {isImageOrVideo} from "../utils/utils.js";
import {config as browserPoolConfig} from "../config/spider.js";

const {headless, poolSize} = browserPoolConfig;
EventEmitter.setMaxListeners(0);

const queue = [];
for (let i = 0; i < poolSize; i++) {
  const browser = await puppeteer.launch({headless});
  queue.push(browser);
}

/**
 * 获取一个新的浏览器实例
 * @returns {Promise<Browser|*>}
 */
const getBrowser = async () => {
  // if (queue.length === 0) {
  //   return await puppeteer.launch({headless});
  // }
  // let res = queue.shift();
  // return res;
  return new Promise((resolve, reject)=> {
    let id = setInterval(()=>{
      if(queue.length) {
        resolve(queue.shift());
        clearInterval(id);
      }
    }, 1000);
  });
};

/**
 * 获取浏览器的网页并阻止该网页内的图片和视频请求这样可以防止超时问题
 * @param browser
 * @returns {Promise<*>}
 */
const getBrowserPageWithoutPicAndVideo = async (browser) => {
  // 获取page
  let page = await browser.newPage();
  await page.setRequestInterception(true);
  page.on('request', (request) => {
    const url = request.url();
    if (isImageOrVideo(url)) {
      request.abort();
    } else {
      request.continue();
    }
  });
  return page;
};
/**
 * 归还浏览器重新返回内存中，方便复用
 * @param browser
 */
const backBrowser = async (browser) => {
  let pages = await browser.pages();
  // 要留一个不然browser就关闭了 后面newPage就卡死了
  if (pages.length > 1) {
    // 关闭页面
    for (let i = 1; i < pages.length; i++) {
      let page = pages[i];
      await page.close();
    }
  }
  if (queue.length >= poolSize) {
    await browser.close();
    return;
  }
  queue.push(browser);
};
/**
 * 销毁原来的出错的浏览器实例并创建一个新的放入缓存中
 * @param browser
 * @returns {Promise<void>}
 */
const browserUpdate = async (browser) => {
  await browser.close();
  if (queue.length >= poolSize) {
    return;
  }
  const browserNew = await puppeteer.launch({headless});
  queue.push(browserNew);
};
export default {
  getBrowser,
  backBrowser,
  browserUpdate,
  getBrowserPageWithoutPicAndVideo
};

